package com.bdqn.t320.bootsecurity.config;

import com.bdqn.t320.bootsecurity.controller.LogoutSuccessHandlerConfig;
import com.bdqn.t320.bootsecurity.service.UserService;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.web.authentication.rememberme.JdbcTokenRepositoryImpl;
import org.springframework.security.web.authentication.rememberme.PersistentTokenRepository;

import javax.annotation.Resource;
import javax.sql.DataSource;

@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {

    @Resource
    UserService userService;

    @Resource
    DataSource dataSource;

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        System.out.println("configure.......................");
        //【注意事项】放行资源要放在前面，认证的放在后面
        http
                .csrf().disable()//网络安全暂时关闭,禁止csrf 跨站请求保护
                .formLogin() //开启登录页面,默认登录页面/login
                .loginPage("/login").permitAll() //配置登录页面并对该页面进行授权配置
                .loginProcessingUrl("/dologin")//登录controller请求
                .usernameParameter("username") //指定登录界面用户名文本框的name值，如果没有指定，默认属性名必须为username
                .passwordParameter("password")//指定登录界面密码密码框的name值，如果没有指定，默认属性名必须为password
                .successForwardUrl("/dologin")  //认证成功 forward 跳转路径,始终在认证成功之后跳转到指定请求
                .and()
                .logout().logoutUrl("/logout").logoutSuccessHandler(new LogoutSuccessHandlerConfig()).clearAuthentication(true).invalidateHttpSession(true)
                .and()
                .authorizeRequests()
                .antMatchers("/","/images/**", "/js/**", "/css/**", "/fonts/**", "/localcss/**", "/localjs/**").permitAll()
                .antMatchers("/timeout").permitAll()
                .antMatchers("/logout").permitAll()
                .anyRequest().access("@myRBACService.hasPermission(request,authentication)")
      /*          .antMatchers("/admin").hasRole("admin")
                .antMatchers("/user").hasAuthority("ROLE_user")*/
               // .anyRequest().authenticated()//任何请求都需要经过验证
                .and()
                .sessionManagement()
                .invalidSessionUrl("/timeout")
                .and()
                .rememberMe()
                .tokenValiditySeconds(2000)  //默认14天
                .rememberMeParameter("remember-me")
                .tokenRepository(persistentTokenRepository())//设置token仓库
        //.rememberMeCookieName()  //客户端保存cookie的值
        ;
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        //基于内存认证授权
//        auth.inMemoryAuthentication()
//                .passwordEncoder(new BCryptPasswordEncoder())
//                .withUser("admin").password("$2a$10$nVGoX3KHyltKclPNNkOV6e8dOLGZxesKuwKW3ZEuUD.0/7Wm01jN.").authorities("admin")
//                .and()
//                .withUser("user").password("$2a$10$nVGoX3KHyltKclPNNkOV6e8dOLGZxesKuwKW3ZEuUD.0/7Wm01jN.").roles("user");
        //基于数据库认证授权
        auth.userDetailsService(userService).passwordEncoder(new BCryptPasswordEncoder());
    }


    public PersistentTokenRepository persistentTokenRepository() {
        JdbcTokenRepositoryImpl tokenRepository = new JdbcTokenRepositoryImpl();
        //设置数据源
        tokenRepository.setDataSource(dataSource);
        //自动创建表,这里就不让程序自动创建表，咱们自己主动创建
        //创建表的sql语句在JdbcTokenRepositoryImpl类中的initDao方法
        //create table persistent_logins (username varchar(64) not null, series varchar(64) primary key, token varchar(64) not null, last_used timestamp not null)
        //tokenRepository.setCreateTableOnStartup(true);
        return tokenRepository;
    }

}
